iT邦幫忙

2024 iThome 鐵人賽

DAY 20
0
Mobile Development

用Spring Boot架設後端結合Android前端建構智慧個人化推薦系統系列 第 20

Day20 Spring Security 保護你的RESTful API:各種安全性措施的實作

  • 分享至 

  • xImage
  •  

在當今的網路環境中,保障 RESTful API 的安全性變得越來越重要。無論是企業應用還是個人專案,保護你的 API 免受未經授權的訪問與攻擊都是開發過程中的一個重要課題

在使用 Spring Security 保護 RESTful API 之前,首先需要在你的 Spring Boot 專案中添加相關的依賴。在 pom.xml 中添加如下依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

在 RESTful API 中,最常見的身份驗證方式是基本身份驗證。你可以通過覆寫 configure 方法來設定基本身份驗證

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user")
            .password("{noop}password") // {noop}表示不加密
            .roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable() // 禁用 CSRF,適用於 RESTful API
            .authorizeRequests()
            .anyRequest().authenticated() // 所有請求都需要認證
            .and()
            .httpBasic(); // 啟用基本身份驗證
    }
}

使用 JWT (JSON Web Tokens)

JWT 是目前非常流行的一種身份驗證方式。相較於基本身份驗證,JWT 更加靈活且安全。以下是使用 JWT 的基本實作
在 pom.xml 中加入 JWT 的依賴

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

首先,創建一個 JWT 工具類來生成與驗證令牌

@Component
public class JwtTokenUtil {
    private final String SECRET_KEY = "your_secret_key"; // 請務必更改此值

    public String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) // 10 小時後過期
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

    public Claims extractClaims(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();
    }

    public String extractUsername(String token) {
        return extractClaims(token).getSubject();
    }

    public boolean isTokenExpired(String token) {
        return extractClaims(token).getExpiration().before(new Date());
    }

    public boolean validateToken(String token, String username) {
        return (extractUsername(token).equals(username) && !isTokenExpired(token));
    }
}

接下來,創建一個過濾器來攔截請求並驗證 JWT

public class JwtRequestFilter extends WebAuthenticationFilter {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        final String authorizationHeader = request.getHeader("Authorization");

        String username = null;
        String jwt = null;

        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
            jwt = authorizationHeader.substring(7);
            username = jwtTokenUtil.extractUsername(jwt);
        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            // 驗證邏輯
        }

        chain.doFilter(request, response);
    }
}

根據不同的角色或權限限制 API 存取,例如使用以下程式碼設定 API 的端點

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
        .authorizeRequests()
        .antMatchers("/admin/**").hasRole("ADMIN") // 只有 ADMIN 角色可以訪問
        .antMatchers("/user/**").hasAnyRole("USER", "ADMIN") // USER 和 ADMIN 都可以訪問
        .anyRequest().authenticated()
        .and()
        .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}

在 RESTful API 中,通常建議禁用 CSRF 保護,因為大多數 API 是無狀態的。然而,如果你的 API 需要 CSRF 保護,可以使用以下程式碼啟用

http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());

設定 CORS

為了允許從不同來源進行訪問,你可以設定 CORS

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedOrigins("http://localhost:3000");
        }
    };
}

使用 Spring Security 來保護你的 RESTful API 是一個明智的選擇。通過實施身份驗證、授權、CSRF 保護和 CORS 設定,你的 API 將能夠抵禦大多數潛在的安全威脅


上一篇
Day19 Spring Security 角色與權限管理:如何實現細緻的權限控管
下一篇
Day21 Spring Security 使用OAuth2進行社交媒體登入:如何整合第三方登入方式
系列文
用Spring Boot架設後端結合Android前端建構智慧個人化推薦系統30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言